package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.mapper.DRolePowerMapper;
import org.example.pojo.DRole;
import org.example.pojo.DRolePower;
import org.example.pojo.DStaff;
import org.example.pojo.select.DRoleSelect;
import org.example.service.DRoleService;
import org.example.mapper.DRoleMapper;
import org.example.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.stream.Collectors;

/**
* @author chenhongkai
* @description 针对表【d_role】的数据库操作Service实现
* @createDate 2024-06-24 09:10:05
*/
@Service
public class DRoleServiceImpl extends ServiceImpl<DRoleMapper, DRole>
    implements DRoleService{

    @Autowired
    private DRoleMapper dRoleMapper;

    @Autowired
    private DRolePowerMapper dRolePowerMapper;

    @Override
    public Result<Map> SelectAllRoles(DRoleSelect dRoleSelect) {
        //角色信息
        Page<DStaff> page = new Page<>(dRoleSelect.getCurrentPage(),dRoleSelect.getPageSize());
        IPage<Map> mapIPage = dRoleMapper.SelectAllRoles(page,dRoleSelect);

        Map RoleMap = new HashMap<>();
        RoleMap.put("pageSize",mapIPage.getSize());
        RoleMap.put("pageTotal",mapIPage.getTotal());

        //角色拥有的权限信息
        for(Map role : mapIPage.getRecords()){
            List<DRolePower> dRolePowers = dRolePowerMapper.selectPower(role.get("role_id"));
            role.put("powers",dRolePowers);
        }
        RoleMap.put("roleData",mapIPage.getRecords());

        return Result.ok(RoleMap);
    }

    @Override
    public Result<Map> AddRole(DRoleSelect dRoleSelect) {
        LambdaQueryWrapper<DRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DRole::getRoleName,dRoleSelect.getRoleName());
        DRole dRole1 = dRoleMapper.selectOne(lambdaQueryWrapper);
        //是否重复角色名称
        if(dRole1 != null) return Result.warning(501,"存在相同的角色名");

        //返回新建角色ID
        dRoleMapper.insertRole(dRoleSelect);
        Integer roleId = dRoleSelect.getRoleId();

        //绑定新建角色的权限
        for(Integer powerid : dRoleSelect.getPowersId()){
            DRolePower dRolePower = new DRolePower();
            dRolePower.setPowerId(powerid);
            dRolePower.setRoleId(roleId);
            dRolePowerMapper.insert(dRolePower);
        }
        return Result.ok(null);
    }

    @Override
    public Result<Map> UpdateRoleState(DRole dRole) {
        int row = dRoleMapper.updateById(dRole);
        if(row == 0) return Result.error("更改角色状态失败");
        return Result.ok(null);
    }

    @Override
    public Result<Map> DeleteRole(DRole dRole) {
        int row = dRoleMapper.deleteById(dRole);
        if(row == 0) return Result.error("删除角色失败");
        return Result.ok(null);
    }

    @Override
    public Result<DRole> SelectRoleOne(DRole dRole) {
        //搜索指定角色
        LambdaQueryWrapper<DRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DRole::getRoleId,dRole.getRoleId());
        DRole selectRole = dRoleMapper.selectOne(lambdaQueryWrapper);

        //角色拥有的权限
        List<Integer> powersId = dRoleMapper.selectPowerByRoleId(dRole.getRoleId());
        selectRole.setPowersId(powersId);

        return Result.ok(selectRole);
    }

    @Override
    public Result<DRole> UpdateRoleOne(DRoleSelect dRoleSelect) {

        LambdaQueryWrapper<DRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.eq(DRole::getRoleId,dRoleSelect.getRoleId());
        DRole dRole1 = dRoleMapper.selectOne(roleLambdaQueryWrapper);

        //是否改角色名称
        if(!Objects.equals(dRoleSelect.getRoleName(), dRole1.getRoleName())){
            //是否重复角色名称
            LambdaQueryWrapper<DRole> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DRole::getRoleName,dRoleSelect.getRoleName());
            DRole dRole2 = dRoleMapper.selectOne(lambdaQueryWrapper);
            if(dRole2 != null)
                return Result.warning(501,"存在相同的角色名");
        }

        //修改角色信息
        DRole dRole = new DRole();
        dRole.setRoleId(dRoleSelect.getRoleId());
        dRole.setRoleName(dRoleSelect.getRoleName());
        dRole.setRoleDescription(dRoleSelect.getRoleDescription());
        dRole.setRoleType(dRoleSelect.getRoleType());
        dRole.setRoleStatus(dRoleSelect.getRoleStatus());
        dRole.setUpdateDate(new Date());
        dRoleMapper.updateById(dRole);

        //查出角色拥有的权限
        LambdaQueryWrapper<DRolePower> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DRolePower::getRoleId,dRoleSelect.getRoleId());
        Integer[] powersId = dRolePowerMapper.selectPowerId(dRoleSelect.getRoleId());

        //检查修改的权限和原先权限的差异，寻找被添加和删除的权限
        Set<Integer> set1 = new HashSet<>(Arrays.asList(dRoleSelect.getPowersId()));
        Set<Integer> set2 = new HashSet<>(Arrays.asList(powersId));
        set1.removeAll(set2);
        Set<Integer> set3 = new HashSet<>(Arrays.asList(powersId));
        Set<Integer> set4 = new HashSet<>(Arrays.asList(dRoleSelect.getPowersId()));
        set3.removeAll(set4);

        //set1增加的权限
        for(Integer powerId : set1){
            DRolePower dRolePower = new DRolePower();
            dRolePower.setRoleId(dRoleSelect.getRoleId());
            dRolePower.setPowerId(powerId);
            dRolePowerMapper.insert(dRolePower);
        }
        //set2去除的权限
        for(Integer powerId : set3){
            LambdaQueryWrapper<DRolePower> lambdaQueryWrapperPower = new LambdaQueryWrapper<>();
            lambdaQueryWrapperPower.eq(DRolePower::getRoleId,dRoleSelect.getRoleId())
                            .eq(DRolePower::getPowerId,powerId);
            dRolePowerMapper.delete(lambdaQueryWrapperPower);
        }

        return Result.ok(null);
    }
}






